package com.micro.ai.gateway.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

import java.util.concurrent.TimeUnit;

/**
 * 令牌黑名单服务（响应式版本）
 * 
 * @author micro-ai
 * @since 0.0.1
 */
@Slf4j
@Service
public class TokenBlacklistService {

    @Autowired
    private RedisService redisService;

    private static final String BLACKLIST_PREFIX = "token:blacklist:";

    /**
     * 将令牌加入黑名单
     * 
     * @param token 令牌
     * @param expiresIn 过期时间（秒）
     */
    public Mono<Void> addToBlacklist(String token, long expiresIn) {
        String key = BLACKLIST_PREFIX + token;
        return redisService.set(key, "1", expiresIn, TimeUnit.SECONDS)
                .doOnSuccess(result -> log.info("令牌已加入黑名单: token={}, expiresIn={}s", 
                    token.substring(0, Math.min(20, token.length())) + "...", expiresIn))
                .doOnError(error -> log.error("令牌加入黑名单失败: token={}, error={}", 
                    token.substring(0, Math.min(20, token.length())) + "...", error.getMessage()))
                .then();
    }

    /**
     * 检查令牌是否在黑名单中
     * 
     * @param token 令牌
     * @return 是否在黑名单中
     */
    public Mono<Boolean> isBlacklisted(String token) {
        String key = BLACKLIST_PREFIX + token;
        return redisService.hasKey(key)
                .doOnSuccess(blacklisted -> {
                    if (blacklisted) {
                        log.debug("令牌在黑名单中: token={}", token.substring(0, Math.min(20, token.length())) + "...");
                    }
                })
                .doOnError(error -> log.error("检查令牌黑名单失败: token={}, error={}", 
                    token.substring(0, Math.min(20, token.length())) + "...", error.getMessage()))
                .onErrorReturn(false); // 出错时返回false，允许访问
    }

    /**
     * 从黑名单中移除令牌
     * 
     * @param token 令牌
     */
    public Mono<Void> removeFromBlacklist(String token) {
        String key = BLACKLIST_PREFIX + token;
        return redisService.delete(key)
                .doOnSuccess(deleted -> log.info("令牌已从黑名单移除: token={}", 
                    token.substring(0, Math.min(20, token.length())) + "..."))
                .doOnError(error -> log.error("从黑名单移除令牌失败: token={}, error={}", 
                    token.substring(0, Math.min(20, token.length())) + "...", error.getMessage()))
                .then();
    }

    /**
     * 清理过期的黑名单令牌
     */
    public Mono<Void> cleanExpiredTokens() {
        // Redis会自动清理过期的键，这里可以添加额外的清理逻辑
        log.info("清理过期令牌黑名单");
        return Mono.empty();
    }
}
